<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "https://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="zh-CN" />
<!--[if lt IE 9]><style type="text/css">@font-face { font-family: "JinBuGuoWebMono"; src: url("/d/mono.eot"); }</style><![endif]-->
<style media="all" type="text/css">
@font-face { font-family: "JinBuGuoWebMono"; src: url("http://www.jinbuguo.com/d/mono.ttf") format("truetype"); }
* { font-family: "JinBuGuoWebMono", "Ubuntu Mono", "Consolas", "Menlo", monospace; }
body { margin:10px; }
h1,h2 { text-align:center; background:#ddd; }
h2 { margin: 10px 5%; }
h2#auth_name {  background:#fff; }
dt { margin-top: 0.5em; color:#600; }
pre { background: #edc; }
</style>
<title>HotSpot选项笔记 [金步国]</title>
<script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?d286c55b63a3c54a1e43d10d4c203e75"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script>
</head>

<body>
<h1>HotSpot选项笔记</h1><h2 id="auth_name">作者：<strong><a href="../index.html">金步国</a></strong></h2>
<hr />
<h3>版权声明</h3>
<p>本文作者是一位开源理念的坚定支持者，所以本文虽然不是软件，但是遵照开源的精神发布。</p>
<ul>
<li>无担保：本文作者不保证作品内容准确无误，亦不承担任何由于使用此文档所导致的损失。</li>
<li>自由使用：任何人都可以自由的<u>阅读/链接/打印</u>此文档，无需任何附加条件。</li>
<li>名誉权：任何人都可以自由的<u>转载/引用/再创作</u>此文档，但必须保留作者署名并注明出处。</li>
</ul>
<h3>其他作品</h3>
<p>本文作者十分愿意与他人分享劳动成果，如果你对我的其他翻译作品或者技术文章有兴趣，可以在如下位置查看现有的作品集：</p>
<ul>
<li><a href="../index.html">金步国作品集</a> [ <a href="../index.html">http://www.jinbuguo.com/</a> ]</li>
</ul>
<h3>联系方式</h3>
<p>由于作者水平有限，因此不能保证作品内容准确无误。如果你发现了作品中的错误(哪怕是错别字也好)，请来信指出，任何提高作品质量的建议我都将虚心接纳。</p>
<ul>
<li>Email(QQ)：70171448在QQ邮箱</li>
</ul>
<hr />




<h2>语法</h2>
<pre>
java [ options ] class [ argument ... ]
java [ options ] -jar file.jar [ argument ... ]
</pre>



<h2>标准选项</h2>
<dl>

<dt>-d32|-d64<br>-client|-server</dt>
<dd>
以客户端模式还是服务器模式执行虚拟机。<br>
服务器模式的特点是启动速度比较慢，但运行时性能和内存管理效率很高，适用于生产环境。<br>
对于64位虚拟机而言，服务器模式是默认值，也是唯一支持的模式。
</dd>

<dt>-agentlib:库名[=启动选项]<br>-agentpath:绝对路径[=启动选项]</dt>
<dd>
从指定的路径(必须是绝对路径)/库名称中加载JVMT Tool Interface agent库(还可传递启动选项)。<br>
例如：
<pre>
-agentlib:foo=opt1,opt2
-agentpath:/opt/lib/foo.so=opt1,opt2
</pre>
</dd>

<dt>-classpath 路径列表<br>-cp 路径列表</dt>
<dd>
指定一个搜索classic文件的目录/JAR/ZIP列表，列表项之间用分号(;)分隔。<br>
这里指定的值将会覆盖CLASSPATH环境变量的设置。<br>
如果既没有指定 -classpath 也没有设置CLASSPATH环境变量，那么其默认值将是用户的当前目录(.)<br>
可以用星号(*)作为通配符，表示目录下的所有.jar文件。单独一个星号表示用户的当前目录下的所有.jar文件。
</dd>

<dt>-D属性=值</dt>
<dd>将系统"属性"设为"值"。如果"值"是一个包含空格的字符串，那么必须用双引号进行界定。</dd>

<dt>-enableassertions[:包名"..." | :类名 ]<br>-ea[:包名"..." | :类名 ]<br>-disableassertions[:包名"..." | :类名 ]<br>-da[:包名"..." | :类名 ]</dt>
<dd>为指定的包或者类启用/禁止断言，默认值为禁止。</dd>

<dt>-enablesystemassertions<br>-esa<br>-disablesystemassertions<br>-dsa</dt>
<dd>仅对所有的系统类启用/禁止断言</dd>

<dt>-jar file.jar</dt>
<dd>执行封装在file.jar文件内的程序。<br>使用此选项后，file.jar文件内必须包含所有的用户class，并且所有-classpath选项都将被忽略。</dd>

<dt>-javaagent:jar文件[=选项]</dt>
<dd>指定jvm启动时装入java语言代理。参见：java.lang.instrument</dd>

<dt>-jre-restrict-search<br>-no-jre-restrict-search</dt>
<dd>在版本搜索的时候，包含/排除用户私人的JRE</dd>

<dt>-verbose<br>-verbose:class</dt>
<dd>输出jvm载入类的相关信息，当jvm报告说找不到类或者类冲突时可此进行诊断。</dd>

<dt>-verbose:gc</dt>
<dd>输出每次垃圾回收的相关情况。</dd>

<dt>-verbose:jni</dt>
<dd>输出native方法调用的相关情况，一般用于诊断jni调用错误信息。</dd>

<dt>-version</dt>
<dd>输出java的版本信息</dd>

<dt>-version:版本信息</dt>
<dd>
指定class或者jar运行时需要的jdk版本信息；若指定版本未找到，则以能找到的系统默认jdk版本执行；<br>
一般情况下，对于jar文件，可以在manifest文件中指定需要的版本信息，而不是在命令行。<br>
"版本信息"中可以指定单个版本，也可以指定一个列表，中间用空格隔开，且支持复杂组合，例如：-version:"1.6.0_13 1.6* & 1.6.0_10+"
</dd>

<dt>-showversion</dt>
<dd>输出java版本信息(与-version相同)之后，继续输出java的标准参数列表及其描述。</dd>

<dt>-?<br>-help</dt>
<dd>输出java标准参数列表及其描述。</dd>

<dt>-X</dt>
<dd>输出非标准的参数列表及其描述。</dd>

</dl>




<h2>非标准选项</h2>
<dl>

<dt>-Xint</dt>
<dd>仅以解释模式运行虚拟机，全部字节码都以解释方式执行</dd>

<dt>-Xcomp</dt>
<dd>仅以编译模式运行虚拟机，优先采用编译方式执行字节码，仅在无法编译的情况下解释器才介入执行</dd>

<dt>-Xmixed</dt>
<dd>以混合模式运行虚拟机，对热点代码使用编译器执行，其他代码使用解释器执行。这是默认值。</dd>

<dt>-Xbatch</dt>
<dd>
禁止后台编译。<br>
默认情况下，对于尚未编译完成的热点代码，虚拟机会先使用解释方式执行，同时将编译任务放到后台。<br>
此选项将会把编译任务放到前台进行，直到编译完成后再继续执行。
</dd>

<dt>-Xbootclasspath:启动类路径<br>-Xbootclasspath/a:路径<br>-Xbootclasspath/p:路径</dt>
<dd>
指定一个分号(;)分隔的目录/JAR/ZIP列表，在其中搜索boot class<br>
此选项用于改变虚拟机自带的系统运行包"rt.jar"，除非你自己能写一个运行时，否则不会用到该参数。<br>
/a:在默认搜索路径后加上path中的搜索路径。<br>
/p:在默认搜索路径前加上path中的搜索路径。
</dd>

<dt>-Xcheck:jni</dt>
<dd>
调用JNI(Java Native Interface)函数时进行额外的检查，特别地，虚拟机将校验传递给JNI函数参数的合法性。<br>
在本地代码中遇到非法数据时，虚拟机将报一个致命错误而终止。使用该参数后将造成性能下降。
</dd>

<dt>-Xfuture</dt>
<dd>
对类文件进行严格的格式检查，以保证类代码严格符合新规范。<br>
为保持向后兼容1.1.x版本的JDK，虚拟机缺省不进行严格的格式检查。<br>
建议明确开启此参数，特别是在开发阶段。
</dd>

<dt>-Xnoclassgc</dt>
<dd>关闭虚拟机对class的垃圾回收功能。很可能会导致OutOfMemoryError异常。</dd>

<dt>-Xincgc</dt>
<dd>
启动增量垃圾收集器(默认关闭)。<br>
增量垃圾收集器能减少偶然发生的长时间垃圾回收造成的暂停时间。<br>
但增量垃圾收集器和应用程序并发执行，因此会抢占部分应用程序的CPU资源。
</dd>

<dt>-Xloggc:文件</dt>
<dd>
将虚拟机每次垃圾回收的信息写到"文件"中，内容和 -verbose:gc 的输出内容相同，但增加了时间戳。<br>
务必指定一个本机文件，以避免因为网络拥堵造成虚拟机停顿。<br>
当文件系统被填满后，日志文件会被自动从头截掉(类似日志滚动)，并继续记录。<br>
如果同时使用了 -verbose:gc 和本选项，那么 -verbose:gc 将会被忽略。
</dd>

<dt>-Xms字节数</dt>
<dd>设置初始Java heap的大小，可以使用K或M或G后缀。建议和-Xmx设为相同。</dd>

<dt>-Xmx字节数</dt>
<dd>设置最大Java heap的大小，可以使用K或M或G后缀。建议和-Xms设为相同。</dd>

<dt>-Xss字节数</dt>
<dd>
设置单个java线程的stack大小，可以使用K或M后缀。<br>
在64bit平台上默认是1024K，在32bit平台上默认是512K。<br>
建议不要设的太大(一般设为256K)，若无特殊情况，512K已经绰绰有余了。
</dd>

<dt>-Xprof</dt>
<dd>对运行中的程序进行性能分析(profile)，并将结果发送到标准输出。仅用于开发目的，切勿用于生产环境！</dd>

<dt>-Xrs</dt>
<dd>
Shutdown Hook功能允许应用程序在终止前(可能是虚拟机自身被终止所致)执行一些诸如关闭数据库连接之类的清理操作。<br>
JVM会注册一个控制台控制句柄(console control handler)，用于捕获要求虚拟机进程终止的控制信号。<br>
该句柄会触发shutdown-hook进程，同时对 SIGHUP, SIGINT, SIGTERM, CTRL_LOGOFF_EVENT 信号返回TURE。<br>
如果JVM是作为service运行(例如Tomcat)，它可以接受CTRL_LOGOFF_EVENT信号但却不应该终止整个进程。<br>
使用该选项之后，JVM将不会注册控制台控制句柄，因此也就不会对上述信号做出响应。<br>
使用此选项会造成如下两个后果：<br>
(1)Ctrl-Break线程转储功能将不可用<br>
(2)应用程序代码必须自己负责触发Shutdown Hook，比如在JVM终止前调用System.exit()方法。
</dd>

</dl>



<h2>不稳定选项</h2>
<p>这些"不稳定"选项的意思是很容易在没有通知的情况下改变。语法格式如下：
<pre>
-XX:+OPT    开启OPT选项
-XX:-OPT    关闭OPT选项
-XX:OPT=VAL 将OPT选项的值设为VAL
</pre>
说明："="后面的内容表示的是此选项的默认值。
<p>

<h3>内存管理参数</h3>
<p>JVM最大总内存 = 线程数*(-Xss) + (-Xmx) + MaxPermSize + MaxDirectMemorySize + ReservedCodeCacheSize</p>
<dl>
<dt>DisableExplicitGC = false</dt>
<dd>忽略程序中System.gc()方法触发的垃圾收集动作</dd>

<dt>MaxDirectMemorySize = -1</dt>
<dd>最大直接内存大小，可以使用K或M或G后缀。默认值"-1"表示使用-Xmx的值。</dd>

<dt>PermSize = [依赖于物理内存大小]</dt>
<dd>永久代区域的初始值，可以使用K或M或G后缀。</dd>

<dt>MaxPermSize = [依赖于物理内存大小]</dt>
<dd>
永久代区域的最大值，可以使用K或M或G后缀。<br>
一些JSP页面可能需要很大的永久代去存放动态生成与加载的类。
</dd>

<dt>NewRatio = 2</dt>
<dd>
老年代对新生代的比例。默认值2表示老年代是新生代大小的2倍。<br>
如果想要更精细的调整新生代的大小，应该使用下面两个参数：
</dd>

<dt>NewSize = [依赖于-Xms,-Xmx的设置]</dt>
<dd>新生代大小的初始值(最小值)，可以把这个参数设成与MaxNewSize相同来固定新生代的大小</dd>

<dt>MaxNewSize = 无穷大</dt>
<dd>新生代大小的最大值(上限)，可以把这个参数设成与NewSize相同来固定新生代的大小</dd>

<dt>SurvivorRatio = 8</dt>
<dd>
新生代中Eden区域与Survivor区域容量的比值。<br>
默认值8表示Eden区的容量是Survivor区的8倍。<br>
因为有两个Survivor区，所以Eden:Survivor1:Survivor2=8:1:1
</dd>

<dt>PretenureSizeThreshold = 0</dt>
<dd>直接晋升到老年代的对象大小阈值(无默认值)，大于这个值的对象将直接在老年代内分配</dd>

<dt>MaxTenuringThreshold = 15</dt>
<dd>
晋升到老年代的对象的年龄阈值。<br>
对象每坚持过一次Minor GC之后，年龄加1，当超过这个阈值之后，该对象将进入老年代
</dd>

<dt>UseAdaptiveSizePolicy = true</dt>
<dd>允许JVM动态调整java堆中老年代、新生代区域的大小以及进入老年代的年龄</dd>

<dt>UseG1GC = false</dt>
<dd>使用G1(Garbage First)垃圾收集器</dd>

<dt>GCTimeRatio = 9</dt>
<dd>垃圾回收时间占总运行时间的比率=1/(1+GCTimeRatio)。默认值9表示最大允许1/(1+9)=10%的时间用于GC</dd>

<dt>MaxGCPauseMillis = 200</dt>
<dd>设置GC最大停顿时间，也就是在垃圾回收时允许正常工作进程最大允许停顿多长时间，单位是毫秒</dd>

<dt>GCPauseIntervalMillis = 201</dt>
<dd>设置两次GC之间的时间间隔，也就是每隔多长时间可以接受一次GC停顿 ，单位是毫秒</dd>

<dt>UseGCOverheadLimit = true</dt>
<dd>
如果有过多的时间花费在垃圾收集上(超过98%)，就抛OutOfMemoryError异常。<br>
这个功能是用来防止堆太小导致程序长时间无法正常工作而设计的。
</dd>

<dt>UseCompressedOops = false</dt>
<dd>指针压缩功能</dd>
</dl>


<h3>即时编译参数</h3>
<dl>
<dt>BackgroundCompilation = true</dt>
<dd>使用后台编译。也就是在将方法编译为本地代码完成之前，先解释执行，而不是暂停执行</dd>

<dt>TieredCompilation = false</dt>
<dd>
启用分层编译策略：C0为解释执行，C1进行可靠优化编译，C2进行激进优化编译。<br>
分层编译可以逐步优化代码，以使最终运行速度更快，且降低C2编译时对执行速度的影响，建议开启。
</dd>

<dt>InitialCodeCacheSize = 4M</dt>
<dd>即时编译器编译的代码缓存的初始值，可以使用K或M或G后缀。</dd>

<dt>ReservedCodeCacheSize = 48M</dt>
<dd>即时编译器编译的代码缓存的最大值，可以使用K或M或G后缀。</dd>

<dt>CompileThreshold = 10000</dt>
<dd>
触发即时编译的阈值。<br>
当调用计数器(用于函数)或者回边计数器(用于代码块)超过此值时，将被编译为机器码
</dd>

<dt>InterpreterProfilePercentage = 33<br>OnStackReplacePercentage = 140</dt>
<dd>
用于计算回边计数器阈值的两个参数，当计算结果大于CompileThreshold时，代码块所在的函数将被编译为机器码。<br>
回边计数器阈值=CompileThreshold*(OnStackReplacePercentage-InterpreterProfilePercentage)/100
</dd>

<dt>UseCounterDecay = true</dt>
<dd>
对方法调用计数器使用热度衰减算法。<br>
建议关闭热度衰减算法，这样，只要运行时间足够长，绝大部分方法都将被编译成本地代码
</dd>
</dl>


<h3>类型加载参数</h3>
<dl>
<dt>UseSplitVerifier = true</dt>
<dd>使用新的Class类型校验器(依赖StackMapTable信息的类型检查)，以加快字节码校验速度，建议启用。</dd>

<dt>FailOverToOldVerifier = true</dt>
<dd>当类型校验失败时，回到老的类型推导校验方式进行校验。建议关闭。</dd>

<dt>RelaxAccessControlCheck = false</dt>
<dd>在校验阶段放松对类型访问性的限制。建议关闭。</dd>
</dl>


<h3>多线程相关参数</h3>
<dl>
<dt>UseBiasedLocking = true</dt>
<dd>
使用<a href="http://kenwublog.com/theory-of-java-biased-locking">偏向锁</a>，它通过消除资源无竞争情况下的同步原语，进一步提高了程序的运行性能。</dd>

<dt>UseSpinning = false</dt>
<dd>使用<a href="http://kenwublog.com/theory-of-lightweight-locking-upon-cas">自旋锁</a>以避免线程频繁的挂起和唤醒，建议开启</dd>

<dt>PreBlockSpin = 10</dt>
<dd>在挂起线程前，使用自旋锁时的最大自旋次数，超过这个次数后，线程将被挂起</dd>

<dt>UseThreadPriorities = true</dt>
<dd>使用线程优先级</dd>

<dt>UseFastAccessorMethods = true</dt>
<dd>当频繁反射执行某个方法时，编译成字节码来加快反射的执行速度</dd>
</dl>


<h3>性能参数</h3>
<dl>
<dt>AggressiveOpts = false</dt>
<dd>使用比较激进的优化特性，这些特性具有双重影响，并不一定能够加速应用的执行</dd>

<dt>UseLargePages = false</dt>
<dd>使用大的内存页，需要操作系统内核的支持。在大内存的机器上建议开启</dd>

<dt>LargePageSizeInBytes = 0</dt>
<dd>设置堆内存的<a href="http://kenwublog.com/tune-large-page-for-jvm-optimization">内存页大小</a>，一般是4M，需要操作系统内核的支持</dd>
</dl>


<h3>调试参数</h3>
<dl>
<dt>PrintCommandLineFlags = false</dt>
<dd>打印当前启用的非稳态选项</dd>

<dt>PrintFlagsFinal = false</dt>
<dd>输出所有不稳定选项的名称及其当前值</dd>

<dt>PrintGCTimeStamps = false</dt>
<dd>打印每次回收开始时间的时间戳，对于查看垃圾回收频率非常有用。</dd>

<dt>ErrorFile =</dt>
<dd>如果JVM崩溃，则将错误日志输出到指定的文件路径。</dd>

<dt>HeapDumpPath =</dt>
<dd>当java进程因OutOfMemory或crash被OS强制终止后，生成一个Heap Profling格式的堆内存快照文件。</dd>
</dl>




<hr />

</body></html>